package com.ghd.dataviz.core.param;

import com.ghd.dataviz.core.constant.ResponseCode;
import com.ghd.dataviz.core.utils.ExceptionUtil;
import com.ghd.dataviz.core.utils.JsonUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @author ：ghd
 * @date ：Created in 2020-03-15 17:21
 * @description：
 * @modified By：
 * @version: $
 */
@Data
@AllArgsConstructor
@ApiModel("返回对象")
public class DatavizResponse<T> {
    private static final int SUCCESS = 1;
    private static final int FAILURE = 0;

    @ApiModelProperty(value = "状态")
    private int status;
    @ApiModelProperty(value = "状态码")
    private ResponseCode code;
    @ApiModelProperty(value = "提示信息/错误信息")
    private String message;
    @ApiModelProperty(value = "数据对象")
    private T data;
    @ApiModelProperty(value = "错误堆栈信息")
    private String stack;


    public static <T> DatavizResponse<T> success(String message) {
        return new DatavizResponse<>(SUCCESS, ResponseCode.SUCCESS, message, null, null);
    }

    public static <T> DatavizResponse<T> success(String message, T data) {
        return new DatavizResponse<>(SUCCESS, ResponseCode.SUCCESS, message, data, null);
    }

    public static <T> DatavizResponse<T> success(T data) {
        return new DatavizResponse<>(SUCCESS, ResponseCode.SUCCESS, ResponseCode.SUCCESS.getDesc(), data, null);
    }

    public static <T> DatavizResponseBuilder<T> failure(ResponseCode code) {
        return DatavizResponse.<T>builder().status(FAILURE).code(code).message(code.getDesc());
    }

    public static <T> DatavizResponse<T> failure(Throwable throwable) {
        return new DatavizResponse<>(FAILURE, ResponseCode.UN_KNOW_EXCEPTION, throwable.getMessage(), null,
                ExceptionUtil.getStackTrace(throwable));
    }


    @Override
    public String toString() {
        return JsonUtil.objectToJson(this);
    }

    public static <T> DatavizResponse.DatavizResponseBuilder<T> builder() {
        return new DatavizResponse.DatavizResponseBuilder<>();
    }

    public static class DatavizResponseBuilder<T> {
        private int status;
        private ResponseCode code;
        private String message;
        private T data;
        private String stack;

        DatavizResponseBuilder() {
        }

        public DatavizResponse.DatavizResponseBuilder<T> status(final int status) {
            this.status = status;
            return this;
        }

        public DatavizResponse.DatavizResponseBuilder<T> code(final ResponseCode code) {
            this.code = code;
            return this;
        }

        public DatavizResponse.DatavizResponseBuilder<T> message(final String message) {
            this.message = message;
            return this;
        }

        public DatavizResponse.DatavizResponseBuilder<T> data(final T data) {
            this.data = data;
            return this;
        }

        public DatavizResponse.DatavizResponseBuilder<T> stack(final Throwable stack) {
            this.stack = ExceptionUtil.getStackTrace(stack);
            return this;
        }

        public <T> DatavizResponse<T> build() {
            return new DatavizResponse<>(this.status, this.code, this.message, (T) this.data, this.stack);
        }

        public String toString() {
            return "DatavizResponse.DatavizResponseBuilder(status=" + this.status + ", code=" + this.code + ", message=" + this.message + ", data=" + this.data + ", stack=" + this.stack + ")";
        }
    }
}
